package org.opencv.SDK;

import android.graphics.Bitmap;
import android.util.Log;
import android.util.Pair;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.List;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.FastResultBean;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.imgproc.Moments;

public class OpenCVUtils {
    public static final int MATCHING_METHOD_DEFAULT = 5;
    public static final int MAX_LEVEL_AUTO = -1;
    private static final String TAG = "OpenCVUtils";

    public enum ColorType {
        RED,
        BLACK,
        GREEN,
        PURPLE,
        WHITE
    }

    public interface OnFindingListener {
        void result(boolean z, FastResultBean fastResultBean);
    }

    private static boolean shouldContinueMatching(int i, int i2) {
        if (i != i2 || i == 0) {
            return i2 > 2 && i == i2 - 1;
        }
        return true;
    }

    public static FastResultBean findOneTarget(Bitmap bitmap, Bitmap bitmap2) {
        if (bitmap != null && bitmap2 != null && !bitmap.isRecycled() && !bitmap2.isRecycled()) {
            long currentTimeMillis = System.currentTimeMillis();
            Mat mat = new Mat();
            Utils.bitmapToMat(bitmap, mat);
            Mat mat2 = new Mat();
            Utils.bitmapToMat(bitmap2, mat2);
            FastResultBean findOneTargetMethod = findOneTargetMethod(mat, mat2);
            Log.d(TAG, System.currentTimeMillis() + "匹配，用时" + (System.currentTimeMillis() - currentTimeMillis));
            if (findOneTargetMethod != null) {
                findOneTargetMethod.setWidth(mat2.cols());
                findOneTargetMethod.setHeight(mat2.rows());
                recyclBitmap(bitmap, bitmap2);
                return findOneTargetMethod;
            }
            recyclBitmap(bitmap, bitmap2);
        }
        return null;
    }

    private static void recyclBitmap(Bitmap... bitmapArr) {
        try {
            for (Bitmap bitmap : bitmapArr) {
                if (bitmap != null && !bitmap.isRecycled()) {
                    bitmap.recycle();
                }
            }
            System.gc();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static List<FastResultBean> findAllTarget(Bitmap bitmap, Bitmap bitmap2, int i, OnFindingListener onFindingListener) {
        if (bitmap == null || bitmap2 == null || bitmap.isRecycled() || bitmap2.isRecycled()) {
            return null;
        }
        long currentTimeMillis = System.currentTimeMillis();
        Mat mat = new Mat();
        Utils.bitmapToMat(bitmap, mat);
        Mat mat2 = new Mat();
        Utils.bitmapToMat(bitmap2, mat2);
        List<FastResultBean> findAllTargetMethod = findAllTargetMethod(mat, mat2, i, onFindingListener);
        Log.d(TAG, "list.size():" + findAllTargetMethod.size());
        Log.d(TAG, System.currentTimeMillis() + "匹配，用时" + (System.currentTimeMillis() - currentTimeMillis));
        if (findAllTargetMethod != null && findAllTargetMethod.size() > 0) {
            for (FastResultBean fastResultBean : findAllTargetMethod) {
                fastResultBean.setWidth(mat2.cols());
                fastResultBean.setHeight(mat2.rows());
            }
        }
        recyclBitmap(bitmap, bitmap2);
        return findAllTargetMethod;
    }

    private static FastResultBean findOneTargetMethod(Mat mat, Mat mat2) {
        float f;
        Mat matchTemplate;
        Mat mat3;
        int selectPyramidLevel = selectPyramidLevel(mat, mat2);
        selectPyramidLevel(mat, mat2);
        double d = 0.0d;
        boolean z = true;
        int i = selectPyramidLevel;
        Point point = null;
        Mat mat4 = null;
        while (i >= 0) {
            Mat pyramidDownAtLevel = getPyramidDownAtLevel(mat, i);
            Mat pyramidDownAtLevel2 = getPyramidDownAtLevel(mat2, i);
            if (point == null) {
                if (!z && !shouldContinueMatching(i, selectPyramidLevel)) {
                    break;
                }
                release(mat4);
                Mat matchTemplate2 = matchTemplate(pyramidDownAtLevel, pyramidDownAtLevel2, 5);
                Pair<Point, Double> bestMatched = getBestMatched(matchTemplate2, 5, 0.1f);
                Point point2 = (Point) bestMatched.first;
                mat3 = pyramidDownAtLevel;
                matchTemplate = matchTemplate2;
                d = ((Double) bestMatched.second).doubleValue();
                point = point2;
            } else {
                Rect roi = getROI(point, pyramidDownAtLevel, pyramidDownAtLevel2);
                release(mat4);
                Mat mat5 = new Mat(pyramidDownAtLevel, roi);
                matchTemplate = matchTemplate(mat5, pyramidDownAtLevel2, 5);
                release(mat5);
                Pair<Point, Double> bestMatched2 = getBestMatched(matchTemplate, 5, 0.1f);
                ((Double) bestMatched2.second).doubleValue();
                point = (Point) bestMatched2.first;
                double doubleValue = ((Double) bestMatched2.second).doubleValue();
                point.x += roi.x;
                point.y += roi.y;
                d = doubleValue;
                mat3 = pyramidDownAtLevel;
            }
            if (mat3 != mat) {
                release(mat3);
            }
            if (pyramidDownAtLevel2 != mat2) {
                pyramidDownAtLevel2.release();
            }
            f = 0.2f;
            if (d >= 0.2f) {
                pyrUp(point, i);
                break;
            }
            i--;
            mat4 = matchTemplate;
            z = false;
        }
        f = 0.2f;
        if (d < f) {
            return null;
        }
        return new FastResultBean((int) point.x, (int) point.y, 0, 0, (int) (d * 100.0d));
    }

    private static List<FastResultBean> findAllTargetMethod(Mat mat, Mat mat2, int i, OnFindingListener onFindingListener) {
        int i2 = 0;
        int i3  = 0;
        int i4  = 0;
        Exception e;
        int i5  = 0 ;
        Mat mat3 = null;
        Rect roi = null;
        Mat mat4 = null;
        Mat matchTemplate =null;
        Mat matchTemplate2 = null;
        int cols = mat2.cols();
        int rows = mat2.rows();
        ArrayList arrayList = new ArrayList();
        int selectPyramidLevel = selectPyramidLevel(mat, mat2);
        selectPyramidLevel(mat, mat2);
        Mat mat5 = null;
        Point point = null;
        int i6 = selectPyramidLevel;
        boolean z = true;
        while (i6 >= 0) {
            try {
                Mat pyramidDownAtLevel = getPyramidDownAtLevel(mat, i6);
                Mat pyramidDownAtLevel2 = getPyramidDownAtLevel(mat2, i6);
                if (point == null) {
                    if (!z) {
                        try {
                            if (!shouldContinueMatching(i6, selectPyramidLevel)) {
                                break;
                            }
                        } catch (Exception e2) {
                            e = e2;
                            i2 = selectPyramidLevel;
                            i3 = cols;
                            i4 = i6;
                            e.printStackTrace();
                            i6 = i4 - 1;
                            cols = i3;
                            selectPyramidLevel = i2;
                        }
                    }
                    try {
                        release(mat5);
                        matchTemplate2 = matchTemplate(pyramidDownAtLevel, pyramidDownAtLevel2, 5);
                        i5 = i6;
                        i2 = selectPyramidLevel;
                    } catch (Exception e3) {
                        e = e3;
                        i2 = selectPyramidLevel;
                        i4 = i6;
                        i3 = cols;
                        e.printStackTrace();
                        i6 = i4 - 1;
                        cols = i3;
                        selectPyramidLevel = i2;
                    }
                    try {
                        Pair<Point, Double> bestMatched01 = getBestMatched01(arrayList, pyramidDownAtLevel, pyramidDownAtLevel2, matchTemplate2, 5, i, onFindingListener, i6, cols, rows);
                        point = (Point) bestMatched01.first;
                        try {
                            ((Double) bestMatched01.second).doubleValue();
                            i3 = cols;
                            mat5 = matchTemplate2;
                            mat3 = pyramidDownAtLevel2;
                        } catch (Exception e4) {
                            e = e4;
                            i3 = cols;
                            mat5 = matchTemplate2;
                            i4 = i5;
                            e.printStackTrace();
                            i6 = i4 - 1;
                            cols = i3;
                            selectPyramidLevel = i2;
                        }
                    } catch (Exception e5) {
                        e = e5;
                        mat5 = matchTemplate2;
                        i4 = i5;
                        point = point;
                        i3 = cols;
                        e.printStackTrace();
                        i6 = i4 - 1;
                        cols = i3;
                        selectPyramidLevel = i2;
                    }
                } else {
                    i5 = i6;
                    i2 = selectPyramidLevel;
                    try {
                        roi = getROI(point, pyramidDownAtLevel, pyramidDownAtLevel2);
                        release(mat5);
                        mat4 = new Mat(pyramidDownAtLevel, roi);
                        matchTemplate = matchTemplate(mat4, pyramidDownAtLevel2, 5);
                    } catch (Exception e6) {
                        e = e6;
                        i3 = cols;
                        i4 = i5;
                        e.printStackTrace();
                        i6 = i4 - 1;
                        cols = i3;
                        selectPyramidLevel = i2;
                    }
                    try {
                        release(mat4);
                        i3 = cols;
                        mat3 = pyramidDownAtLevel2;
                    } catch (Exception e7) {
                        e = e7;
                        i3 = cols;
                        i4 = i5;
                        mat5 = matchTemplate;
                        e.printStackTrace();
                        i6 = i4 - 1;
                        cols = i3;
                        selectPyramidLevel = i2;
                    }
                    try {
                        Pair<Point, Double> bestMatched012 = getBestMatched01(arrayList, pyramidDownAtLevel, pyramidDownAtLevel2, matchTemplate, 5, i, onFindingListener, i5, cols, rows);
                        point = (Point) bestMatched012.first;
                        try {
                            ((Double) bestMatched012.second).doubleValue();
                            point.x += (double) roi.x;
                            point.y += (double) roi.y;
                            mat5 = matchTemplate;
                        } catch (Exception e8) {
                            e = e8;
                            i4 = i5;
                            mat5 = matchTemplate;
                            e.printStackTrace();
                            i6 = i4 - 1;
                            cols = i3;
                            selectPyramidLevel = i2;
                        }
                    } catch (Exception e9) {
                        e = e9;
                        i4 = i5;
                        mat5 = matchTemplate;
                        point = point;
                        e.printStackTrace();
                        i6 = i4 - 1;
                        cols = i3;
                        selectPyramidLevel = i2;
                    }
                }
                if (pyramidDownAtLevel != mat) {
                    try {
                        release(pyramidDownAtLevel);
                    } catch (Exception e10) {
                        e = e10;
                        i4 = i5;
                        e.printStackTrace();
                        i6 = i4 - 1;
                        cols = i3;
                        selectPyramidLevel = i2;
                    }
                }
                if (mat3 != mat2) {
                    mat3.release();
                }
                if (arrayList.size() > 0) {
                    i4 = i5;
                    try {
                        pyrUp(point, i4);
                        break;
                    } catch (Exception e11) {
                        e = e11;
                    }
                } else {
                    i4 = i5;
                    z = false;
                    i6 = i4 - 1;
                    cols = i3;
                    selectPyramidLevel = i2;
                }
            } catch (Exception e12) {
                e = e12;
                i2 = selectPyramidLevel;
                i3 = cols;
                i4 = i6;
                e.printStackTrace();
                i6 = i4 - 1;
                cols = i3;
                selectPyramidLevel = i2;
            }
        }
        return arrayList;
    }

    private static Mat getPyramidDownAtLevel(Mat mat, int i) {
        if (i == 0) {
            return mat;
        }
        int cols = mat.cols();
        int rows = mat.rows();
        for (int i2 = 0; i2 < i; i2++) {
            cols = (cols + 1) / 2;
            rows = (rows + 1) / 2;
        }
        Mat mat2 = new Mat(rows, cols, mat.type());
        Imgproc.resize(mat, mat2, new Size((double) cols, (double) rows));
        return mat2;
    }

    private static void pyrUp(Point point, int i) {
        for (int i2 = 0; i2 < i; i2++) {
            point.x *= 2.0d;
            point.y *= 2.0d;
        }
    }

    private static Rect getROI(Point point, Mat mat, Mat mat2) {
        int max = Math.max(0, (int) ((point.x * 2.0d) - ((double) (mat2.cols() / 4))));
        int max2 = Math.max(0, (int) ((point.y * 2.0d) - ((double) (mat2.rows() / 4))));
        int cols = (int) (((double) mat2.cols()) * 1.5d);
        int rows = (int) (((double) mat2.rows()) * 1.5d);
        if (max + cols >= mat.cols()) {
            cols = (mat.cols() - max) - 1;
        }
        if (max2 + rows >= mat.rows()) {
            rows = (mat.rows() - max2) - 1;
        }
        return new Rect(max, max2, cols, rows);
    }

    private static int selectPyramidLevel(Mat mat, Mat mat2) {
        int log = (int) (Math.log((double) (min(mat.rows(), mat.cols(), mat2.rows(), mat2.cols()) / 16)) / Math.log(2.0d));
        if (log < 0) {
            return 0;
        }
        return Math.min(6, log);
    }

    public static int min(int... iArr) {
        int i = iArr[0];
        for (int i2 = 1; i2 < iArr.length; i2++) {
            if (iArr[i2] < i) {
                i = iArr[i2];
            }
        }
        return i;
    }

    public static Mat matchTemplate(Mat mat, Mat mat2, int i) {
        Mat mat3 = new Mat((mat.rows() - mat2.rows()) + 1, (mat.cols() - mat2.cols()) + 1, CvType.CV_32FC1);
        Imgproc.matchTemplate(mat, mat2, mat3, i);
        return mat3;
    }

    public static Pair<Point, Double> getBestMatched01(List<FastResultBean> list, Mat mat, Mat mat2, Mat mat3, int i, int i2, OnFindingListener onFindingListener, int i3, int i4, int i5) {
        double d;
        Point point;
        int i6;
        String str;
        String str2;
        OnFindingListener onFindingListener2;
        OnFindingListener onFindingListener3 = onFindingListener;
        Core.MinMaxLocResult minMaxLoc = Core.minMaxLoc(mat3);
        int width = mat2.width();
        int height = mat2.height();
        StringBuilder sb = new StringBuilder();
        sb.append("匹配的值001：");
        sb.append(minMaxLoc.maxVal);
        String str3 = "   ------坐标：";
        sb.append(str3);
        sb.append(minMaxLoc.maxLoc.x);
        sb.append(",");
        sb.append(minMaxLoc.maxLoc.y);
        String sb2 = sb.toString();
        String str4 = TAG;
        Log.e(str4, sb2);
        Point point2 = new Point(minMaxLoc.maxLoc.x, minMaxLoc.maxLoc.y);
        pyrUp(point2, i3);
        FastResultBean fastResultBean = new FastResultBean((int) point2.x, (int) point2.y, i4, i5, (int) (minMaxLoc.maxVal * 100.0d));
        list.add(fastResultBean);
        if (onFindingListener3 != null) {
            onFindingListener3.result(true, fastResultBean);
        }
        int i7 = 0;
        while (i7 < 10) {
            double d2 = (double) i2;
            if (minMaxLoc.maxVal * 100.0d > d2) {
                minMaxLoc = getMaxLoc(mat, mat2, width, height, minMaxLoc.maxLoc);
                if (minMaxLoc.maxVal * 100.0d <= d2) {
                    break;
                }
                i6 = i7;
                Imgproc.rectangle(mat, minMaxLoc.maxLoc, new Point(minMaxLoc.maxLoc.x + ((double) width), minMaxLoc.maxLoc.y + ((double) height)), new Scalar(0.0d, 255.0d, 0.0d), 5);
                StringBuilder sb3 = new StringBuilder();
                sb3.append("匹配的值002：");
                sb3.append(minMaxLoc.maxVal);
                str2 = str3;
                sb3.append(str2);
                sb3.append(minMaxLoc.maxLoc.x);
                sb3.append(",");
                sb3.append(minMaxLoc.maxLoc.y);
                str = str4;
                Log.e(str, sb3.toString());
                Point point3 = new Point(minMaxLoc.maxLoc.x, minMaxLoc.maxLoc.y);
                pyrUp(point3, i3);
                FastResultBean fastResultBean2 = new FastResultBean((int) point3.x, (int) point3.y, i4, i5, (int) (minMaxLoc.maxVal * 100.0d));
                list.add(fastResultBean2);
                onFindingListener2 = onFindingListener;
                if (onFindingListener2 != null) {
                    onFindingListener2.result(true, fastResultBean2);
                }
            } else {
                onFindingListener2 = onFindingListener3;
                str = str4;
                i6 = i7;
                str2 = str3;
            }
            i7 = i6 + 1;
            str3 = str2;
            str4 = str;
            onFindingListener3 = onFindingListener2;
        }
        if (i == 0 || i == 1) {
            point = minMaxLoc.minLoc;
            d = -minMaxLoc.minVal;
        } else {
            point = minMaxLoc.maxLoc;
            d = minMaxLoc.maxVal;
        }
        return new Pair<>(point, Double.valueOf(d));
    }

    public static Pair<Point, Double> getBestMatched(Mat mat, int i, float f) {
        Point point;
        double d;
        Core.MinMaxLocResult minMaxLoc = Core.minMaxLoc(mat);
        Log.e(TAG, "匹配的值：" + minMaxLoc.maxVal + "   ------坐标：" + minMaxLoc.maxLoc.x + "," + minMaxLoc.maxLoc.y);
        if (i == 0 || i == 1) {
            point = minMaxLoc.minLoc;
            d = -minMaxLoc.minVal;
        } else {
            point = minMaxLoc.maxLoc;
            d = minMaxLoc.maxVal;
        }
        return new Pair<>(point, Double.valueOf(d));
    }

    private static Core.MinMaxLocResult getMaxLoc(Mat mat, Mat mat2, int i, int i2, Point point) {
        int i3 = (int) point.y;
        int i4 = ((int) point.y) + i2;
        int i5 = ((int) point.x) + i;
        int channels = mat.channels();
        for (int i6 = (int) point.x; i6 < i5; i6++) {
            for (int i7 = i3; i7 < i4; i7++) {
                double[] dArr = mat.get(i7, i6);
                for (int i8 = 0; i8 < channels; i8++) {
                    dArr[i8] = 255.0d;
                }
                mat.put(i7, i6, dArr);
            }
        }
        Mat mat3 = new Mat(new Size((double) ((mat.rows() - mat2.rows()) + 1), (double) ((mat.cols() - mat2.cols()) + 1)), CvType.CV_32FC1);
        Imgproc.matchTemplate(mat, mat2, mat3, 5);
        return Core.minMaxLoc(mat3);
    }

    private static void release(Mat mat) {
        if (mat != null) {
            mat.release();
        }
    }

    public static Bitmap findColorBitmap(Bitmap bitmap, ColorType colorType) {
        Mat mat = new Mat();
        Utils.bitmapToMat(bitmap, mat);
        Mat mat2 = new Mat();
        Imgproc.cvtColor(mat, mat2, 40);
        Mat mat3 = new Mat(mat2.size(), mat2.type());
        Scalar scalar = new Scalar(100.0d, 43.0d, 46.0d);
        Scalar scalar2 = new Scalar(124.0d, 255.0d, 255.0d);
        int i = colorType.ordinal();
        if (i == 1) {
            scalar = new Scalar(100.0d, 43.0d, 46.0d);
            scalar2 = new Scalar(124.0d, 255.0d, 255.0d);
        } else if (i == 2) {
            scalar = new Scalar(0.0d, 0.0d, 0.0d);
            scalar2 = new Scalar(180.0d, 255.0d, 46.0d);
        } else if (i == 3) {
            scalar = new Scalar(36.0d, 25.0d, 25.0d);
            scalar2 = new Scalar(86.0d, 255.0d, 255.0d);
        } else if (i == 4) {
            scalar = new Scalar(125.0d, 43.0d, 46.0d);
            scalar2 = new Scalar(155.0d, 255.0d, 255.0d);
        } else if (i == 5) {
            scalar = new Scalar(0.0d, 0.0d, 221.0d);
            scalar2 = new Scalar(180.0d, 30.0d, 255.0d);
        }
        Core.inRange(mat2, scalar, scalar2, mat3);
        Utils.matToBitmap(mat3, bitmap);
        return bitmap;
    }

    public static void findRectColor(Bitmap bitmap, ImageView imageView) {
        Mat mat = new Mat();
        Mat mat2 = new Mat();
        Mat mat3 = new Mat();
        Utils.bitmapToMat(bitmap, mat);
        Imgproc.GaussianBlur(mat, mat3, new Size(5.0d, 5.0d), 0.0d);
        Imgproc.cvtColor(mat3, mat2, 6);
        Mat mat4 = new Mat(mat3.size(), mat3.type());
        Imgproc.cvtColor(mat3, mat4, 45);
        Imgproc.threshold(mat2, mat2, 60.0d, 255.0d, 0);
        ArrayList<MatOfPoint> arrayList = new ArrayList();
        Imgproc.findContours(mat2, arrayList, new Mat(), 0, 2);
        ColorLabeler colorLabeler = new ColorLabeler();
        for (MatOfPoint matOfPoint : arrayList) {
            Moments moments = Imgproc.moments(matOfPoint);
            int i = (int) (moments.m01 / moments.m00);
            String label = colorLabeler.label(mat4, matOfPoint);
            Imgproc.drawContours(mat, arrayList, -1, new Scalar(0.0d, 255.0d, 0.0d), 2);
            Imgproc.putText(mat, label, new Point((double) ((int) (moments.m10 / moments.m00)), (double) i), 0, 0.5d, new Scalar(255.0d, 255.0d, 255.0d), 2);
            Bitmap createBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565);
            Utils.matToBitmap(mat, createBitmap);
            imageView.setImageBitmap(createBitmap);
        }
    }

    public static Bitmap drawBorder(Bitmap bitmap) {
        Mat mat = new Mat();
        Utils.bitmapToMat(bitmap, mat);
        Mat mat2 = new Mat();
        Imgproc.cvtColor(mat, mat2, 11);
        Imgproc.Canny(mat2, mat2, 20.0d, 60.0d, 3, true);
        ArrayList arrayList = new ArrayList();
        Imgproc.findContours(mat2, arrayList, new Mat(), 0, 2);
        for (int i = 0; i < arrayList.size(); i++) {
            Imgproc.drawContours(mat, arrayList, i, new Scalar(0.0d, 0.0d, 255.0d), -1);
        }
        Utils.matToBitmap(mat2, bitmap);
        return bitmap;
    }
}
